#from strips_engine import *
import strips_engine
def parseDomain(listed_domain):
	iterator = iter(listed_domain)

	if (iterator.next() != "define"):
		raise SyntaxError("No define")
	domain_definition = iterator.next()

	#Check for errors in the domain
	if domain_definition[0] == "domain":
		if len(domain_definition) == 2:
			yield domain_definition[1] # domain name
		else:
			if len(domain_definition) == 1:
				raise SyntaxError("domain Name is not specified")
			else:
				raise SyntaxError("domain has too many parameters")
	else:
		raise SyntaxError("domain doesn't exists ")

	requirements = iterator.next()
	if requirements[0] != ":requirements" or len(requirements) != 2:
		raise SyntaxError("typing requirement is not specified. This planner only parses typed STRIPS!")
	types = iterator.next()
	type_names = []
	if types[0] == ":types" or types[0]==":typing":
		type_names.extend(types[1:])
		constants = iterator.next()
	else:
		raise SyntaxError("types are not specified in the Domain!")
	yield type_names

	if constants[0] == ":constants":
		yield typed_list_x(contants[1:])
		pred = iterator.next()
	else:
		yield []
		pred = constants

	if (pred[0] != ":predicates"):
		raise SyntaxError("No predicates specified in the Domain")

	yield strips_engine.atom_skeleton(pred[1:])


	raw_actions = [action for action in iterator]
	clean_actions = [list(parse_action(act)) for  act in raw_actions]

	yield clean_actions

# return (name, parameter_list, precondition_list, add_list, del_list)
def parse_action(action):
	if type(action) is not list: raise SyntaxError()
	iterator = iter(action)
	a = iterator.next()
	if a != ":action": raise SyntaxError("No Action!")

	name = iterator.next()
	yield name
	
	if iterator.next() != ":parameters": raise SyntaxError("No Parameter!")
	parameters = strips_engine.typed_list_x(iterator.next())
	yield parameters

	# pre-condition is optional
	precon = iterator.next()
	if precon == ":precondition":
		raw_pre = iterator.next()
		preconditions = strips_engine.conjunction(raw_pre,strips_engine.atom)
		yield preconditions

		effect = iterator.next()
	else: effect = precon

	if effect == ":effect":
		raw_effects = iterator.next()
		add_list = [eff[1] for eff in strips_engine.conjunction(raw_effects, strips_engine.literal) if eff[0]==False]
		del_list = [eff[1] for eff in strips_engine.conjunction(raw_effects, strips_engine.literal) if eff[0]==True]
		#print "add:",add_list
		#print "del:",del_list
		yield (add_list,del_list)

	else: raise SyntaxError("Invalid Action: effect not specified!")



